package net.wxxr.http.request;

import java.io.UnsupportedEncodingException;
import java.util.Iterator;

import net.wxxr.dataparse.model.HttpCode;
import net.wxxr.http.auth.BaseAuthSign;
import net.wxxr.http.auth.IAuthSign;
import net.wxxr.http.config.HttpContans;
import net.wxxr.http.config.ResponseHeaderConfig;
import net.wxxr.http.engine.HttpEngine;
import net.wxxr.http.interfaces.IAddCommonHeaders;
import net.wxxr.http.interfaces.IAddCommonParams;
import net.wxxr.http.interfaces.ICheckUser;
import net.wxxr.http.interfaces.IGetLoginoutData;
import net.wxxr.http.interfaces.INetStatus;
import net.wxxr.http.interfaces.IResponseHeaders;
import net.wxxr.http.interfaces.ISaveUserInfoForAutoLoginSuccess;
import net.wxxr.http.interfaces.ITag;
import net.wxxr.http.model.pojo.HttpResult;
import net.wxxr.http.util.CodeUtil;
import net.wxxr.http.util.Constants;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.http.HttpParameters;

import org.apache.http.HttpHost;



/**
 * 向服务器请求基类
 * @author yuanwenfei
 *
 */
public abstract class HttpBaseRequest {

	private String url;

	private HttpParameters urlParams = null;

	private HttpParameters headParams = null;

	private boolean gzip = false;

	/**
	 * 是否需要身份认证
	 */
	private boolean needAuth = false;

	/**
	 * 是否重试
	 */
	private boolean retry = false;

	/**
	 * 是否取消本次请求
	 */
	private boolean cancel = false;
	
	private static IAddCommonHeaders addCommonHeaders;
	
	private static IAddCommonParams addCommonParams;
	public  static IResponseHeaders responseHeaders;
	//获得Cookie超时或失败，获得自动登陆的请求数据的相关接口回调
	public  static IGetLoginoutData IgetloginOutData;
	public static  ISaveUserInfoForAutoLoginSuccess saveUserInfoForAutoLoginSuccess;
	private static ICheckUser checkUser; 
	public static ITag  tag;
	private static INetStatus netStatus;
	
	protected HttpEngine httpEngine;
	
	private static HttpHost httpHost;
	
	protected IAuthSign authSign;

	protected OAuthConsumer consumer;
	
	protected String contentType = HttpContans.CONTENT_TYPE_JSON;
	
	private Object  o;
	
	
	private ResponseHeaderConfig responseHeaderConfig = null;
	
	
	private boolean isDebug = true;
	

	public boolean isDebug() {
		return isDebug;
	}

	public void setDebug(boolean isDebug) {
		this.isDebug = isDebug;
	}

	public ResponseHeaderConfig getResponseHeaderConfig() {
		return responseHeaderConfig;
	}

	public void setResponseHeaderConfig(ResponseHeaderConfig responseHeaderConfig) {
		this.responseHeaderConfig = responseHeaderConfig;
	}

	public Object getO() {
		return o;
	}

	public void setO(Object o) {
		this.o = o;
	}
	

	public String getContentType() {
		return contentType;
	}

	public void setContentType(String contentType) {
		this.contentType = contentType;
	}

	public boolean isCancel() {
		return cancel;
	}
	
	

	/**
	 * 取消此次请求
	 * 
	 * @author yuanwenfei
	 * 
	 */
	public void cancel() {
		this.cancel = true;
		if(httpEngine != null) {
			httpEngine.cancel();
		}
	}

	/**
	 * 指明如何对用户进行登录检查
	 * @param checkUser
	 * @author yuanwenfei
	 * 
	 */
	public static void setCheckUser(ICheckUser checkUser) {
		HttpBaseRequest.checkUser = checkUser;
	}

	/**
	 * 指明需要统一添加哪些参数到所有的url里
	 * @param addSystemInfo
	 * @author yuanwenfei
	 */
	public static void setAddCommonParams(IAddCommonParams addCommonParams) {
		HttpBaseRequest.addCommonParams = addCommonParams;
	}

	public static void setAddCommonHeaders(IAddCommonHeaders addCommonHeaders){
		HttpBaseRequest.addCommonHeaders = addCommonHeaders;
	}
	
	public static void setResponseHeaders(IResponseHeaders responseHeaders){
		HttpBaseRequest.responseHeaders = responseHeaders;
	}
	
	public static void setGetLoginoutData(IGetLoginoutData getLoginOutData){
		HttpBaseRequest.IgetloginOutData = getLoginOutData;
	}
	
	public static void setSaveUserInfoForAutoLoginSuccess(ISaveUserInfoForAutoLoginSuccess saveUserInfo){
		HttpBaseRequest.saveUserInfoForAutoLoginSuccess = saveUserInfo; 
	}
	public static void setITag(ITag  tag){
		HttpBaseRequest.tag = tag;
	}
	
	/**
	 * 指明如何对网络状态进行检查
	 * @param netStatus
	 * @author yuanwenfei
	 */
	public static void setNetStatus(INetStatus netStatus) {
		HttpBaseRequest.netStatus = netStatus;
	}

	/**
	 * 设置httpHost代理
	 * @param httpHost
	 * @author yuanwenfei
	 */
	public static void setHttpHost(HttpHost httpHost) {
		HttpBaseRequest.httpHost = httpHost;
	}

	public HttpParameters getUrlParams() {
		return urlParams;
	}

	public void setUrlParams(HttpParameters urlParams) {
		this.urlParams = urlParams;
	}

	public HttpParameters getHeadParams() {
		return headParams;
	}

	public void setHeadParams(HttpParameters headParams) {
		this.headParams = headParams;
	}

	public boolean isGzip() {
		return gzip;
	}

	public boolean isNeedAuth() {
		return needAuth;
	}

	public void setGzip(boolean gzip) {
		this.gzip = gzip;
	}
    
	public void setNeedAuth(boolean needAuth) {
		this.needAuth = needAuth;
	}

	/**
	 * 若需要Auth认证，则调用此方法
	 * @param consumer OAuthConsumer的对象
	 * @param authSign 如何签名：实现IAuthSign接口，实现sign方法。若传Null则使用默认的签名方法
	 * @author yuanwenfei
	 */
	public void sign(OAuthConsumer consumer, IAuthSign authSign) {
		//this.needAuth = false;
		this.consumer = consumer;
		this.authSign = authSign;
	}
	
	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public boolean isRetry() {
		return retry;
	}

	public void setRetry(boolean retry) {
		this.retry = retry;
	}

	/**
	 * 向urlParams添加一个数据
	 * 
	 * @param key
	 * @param value
	 */
	public void addUrlParams(String key, String value) {
		if (this.urlParams == null) {
			this.urlParams = new HttpParameters();
		}

		this.urlParams.put(key, value);
	}

	/**
	 * 向headParams添加一个数据
	 * 
	 * @param key
	 * @param value
	 */
	public void addHeadParams(String key, String value) {
		if (this.headParams == null) {
			this.headParams = new HttpParameters();
		}

		this.headParams.put(key, value);
	}

	/**
	 * 发起请求后统一调用，<组装URL。。。>
	 * 
	 * @return 返回HttpCode错误码
	 * @throws UnsupportedEncodingException 
	 */
	public HttpCode prepareRequest() throws UnsupportedEncodingException {
		HttpCode code;

		if(netStatus != null) {
			if(!netStatus.isNetAvaliable()) {
				code = HttpCode.ERROR_NO_CONNECT;
				return code;
			}
		}
		
		/**
		 * 检查URL是否正确，已经是否有用户信息
		 */
		code = checkUrlParams();

		if (code == HttpCode.STATUS_OK) {

			/**
			 * 参数检查成功
			 */
			makeUrlWithCommonInfo();
		}

		return code;
	}
	
	/**
	 * 检测URL的有效性
	 * 
	 * @return
	 */
	protected HttpCode checkUrlParams() {
		if (this.url == null || this.url.equals("")) {
			return HttpCode.ERROR_NET_ACCESS;
		}

		if(checkUser != null) {
			if(!checkUser.isUserLegal(needAuth)) {
				return HttpCode.ERROR_NO_REGISTER;
			}
		}
		
		return HttpCode.STATUS_OK;
	}

	/**
	 * 正常逻辑下返回组装后的URL，包含版本信息等
	 * 
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	protected void makeUrlWithCommonInfo() throws UnsupportedEncodingException {
		
		if(headParams == null) {
			headParams = new HttpParameters();
		}
		
		if(addCommonHeaders != null) {
			addCommonHeaders.addCommonHeaders(headParams);
		}
		
		if (this.urlParams == null) {
			this.urlParams = new HttpParameters();
		}

		StringBuilder sb = new StringBuilder();
		if (this.url.contains("?")) {
			sb.append(this.url + "&");
		} else {
			sb.append(this.url + "?");
		}

		//添加通用参数与系统信息有关的参数
		if(addCommonParams != null) {
			addCommonParams.addCommonParams(urlParams);
		}

		Iterator<String> iterator = this.urlParams.keySet().iterator();
		int size = this.urlParams.keySet().size();
		int index = 0;
		while (iterator.hasNext()) {
			index++;
			Object key = iterator.next();
			String value = this.urlParams.getFirst(key);
			// 在参数不为空的情况下组装，否则服务器会报错401
			if (index == size) {
				if (!"".equals(value)) {
					sb.append(key + "=" + CodeUtil.urlEncode(value));
				}
			} else {
				if (!"".equals(value)) {
					sb.append(key + "=" + CodeUtil.urlEncode(value) + "&");
				}
			}
		}
		
		/**
		 * 合成URL
		 */
		this.url = sb.toString();
		
		//若最终没加任何参数，则把?或者&去掉
		if(index == 0) {
			url = url.substring(0, url.length() - 1);
		}
		
		if(this.isDebug) {
			System.out.println("HttpBaseRequest  url: " + url);
		}
	}

	@Override
	public String toString() {
		return "BaseHttpRequest [url=" + url + ", urlParams=" + urlParams + ", headParams=" + headParams + ", gzip=" + gzip + ", needAuth="
				+ needAuth + ", retry=" + retry + "]";
	}

	protected abstract void initHttpEngine();
	
	/**
	 * 执行此次网络请求
	 * @return
	 * @throws Exception
	 * @author yuanwenfei
	 */
	public HttpResult executeRequest() throws UnsupportedEncodingException{
		initHttpEngine();
		if(needAuth) {
			initAuthSign();
			httpEngine.setAuthSign(authSign);
		}
		httpEngine.setHttpHost(httpHost);
		HttpResult result = httpEngine.execute();
		return result;
	}

	/**
	 * 如果用户没有设置authSign，则自动添加一默认的
	 * 
	 * @author yuanwenfei
	 */
	protected void initAuthSign() {
		if(authSign == null) {
			authSign = new BaseAuthSign(consumer);
		}
	}
}
